package omq.xml;

import java.util.Map;

import omq.constants.OmqConstants;
import omq.xml.element.XmlElement;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class OmqXmlUtil extends AXmlUtil{
	
	/**
	 * This is the implementation of the abstract method from the IXmlUtil interface.
	 * It gets an XML element and convert it to XmlElement object.
	 */
	public Object handleElement(Element e) {
		XmlElement xmlElement = new XmlElement();
		NodeList list = e.getChildNodes();
		xmlElement.setElementName(e.getNodeName());
		for(int i = 0; i < list.getLength(); i++){
			Node n = list.item(i);
			short nodeType = n.getNodeType();
			if(nodeType == Node.ELEMENT_NODE){
				Element innerElement =(Element) n;
				xmlElement.addElement((XmlElement)handleElement(innerElement));
			}
			if(nodeType == Node.TEXT_NODE){
				xmlElement.setNodeValue(n.getNodeValue());
			}
		}
		return xmlElement;
	}
	
	
	public XmlElement generateRequestXml(String action,Map params){
		
		XmlElement root = new XmlElement();
		root.setElementName(OmqConstants.DOCUMENT_ROOT_TAG);
		XmlElement header = createRequestHeader(action);
		XmlElement auth = createRequestAuthz((String)params.get(OmqConstants.MAP_PARAM_USER),(String)params.get(OmqConstants.MAP_PARAM_PASSWORD));
		XmlElement queueMgr = createRequestMsg((String)params.get(OmqConstants.MAP_PARAM_QMGR_NAME),(String)params.get(OmqConstants.MAP_PARAM_QUEUE_NAME),transformObject(params.get(OmqConstants.MAP_PARAM_MESSAGE_CONTENT)),(String)params.get(OmqConstants.MAP_PARAM_MESSAGE_ID));
		XmlElement session = createRequestSession((String)params.get(OmqConstants.MAP_PARAM_SESSION_ID),(String)params.get(OmqConstants.MAP_PARAM_SESSION_TRANSACTIONAL),(String)params.get(OmqConstants.MAP_PARAM_SESSION_NUM_OF_MSGS));

		root.addElement(queueMgr);
		root.addElement(header);
		root.addElement(auth);
		root.addElement(session);
		return root;
	}
	
	/**
	 * Creating the header element and its children :
	 *  <header>
	 *  	<version>0.1</version>
     *     	<action>[#CDATA]</action>
     *  </header>
	 */
	private XmlElement createRequestHeader(String action){
		//Element header - The main header element, under it will be action element and version element
		XmlElement header = new XmlElement();
		header.setElementName(OmqConstants.HEADER_ELEMENT);
		header.setId(OmqConstants.HEADER_ELEMENT);		
		//Element version
		XmlElement version = new XmlElement();
		version.setElementName(OmqConstants.HEADER_VERSION_ELEMENT);
		version.setNodeValue(OmqConstants.HEADER_VERSION_VALUE);
		version.setId(OmqConstants.HEADER_VERSION_ELEMENT);
		//Element action
		XmlElement actionEl = new XmlElement();
		actionEl.setElementName(OmqConstants.HEADER_ACTION_ELEMENT);
		actionEl.setId(OmqConstants.HEADER_ACTION_ELEMENT);
		actionEl.setNodeValue(action);
		
		header.addElement(actionEl);
		header.addElement(version);
		
		return header;
	}
	
	/**
	 * Creating the Authentication element and its children :
	 *  <authentication>
     *      <password>[#CDATA]</password>
     *      <login>[#CDATA]</login>
     *	</authentication>
	 */
	private XmlElement createRequestAuthz(String user,String pwd){
		//Element authentication - under root
		XmlElement authentication = new XmlElement();
		authentication.setElementName(OmqConstants.AUTHZ_ELEMENT);
		authentication.setId(OmqConstants.AUTHZ_ELEMENT);	
		//Element login
		XmlElement login = new XmlElement();
		login.setElementName(OmqConstants.AUTHZ_USER_ELEMENT);
		login.setId(OmqConstants.AUTHZ_USER_ELEMENT);
		login.setNodeValue(user);
		//Element login
		XmlElement password = new XmlElement();
		password.setElementName(OmqConstants.AUTHZ_PASSWORD_ELEMENT);
		password.setId(OmqConstants.AUTHZ_PASSWORD_ELEMENT);
		password.setNodeValue(pwd);
		
		authentication.addElement(password);
		authentication.addElement(login);
		return authentication;
	}

	/**
	 * Creating the queue manager element and its children :
	 * <queue_manager>
	 * 	   <name>[#CDATA]</name>
	 *     <queue>
	 *     		<name>[#CDATA]</name>
	 *          <message>
	 *              <body>[#CDATA]</body>
	 *          </message>
	 *      </queue>
	 *  </queue_manager>
	 */
	private XmlElement createRequestMsg(String queueMgrName,String queueName, String msg,String messageId){
		XmlElement queueMgr = new XmlElement();
		queueMgr.setElementName(OmqConstants.QUEUE_MANAGER_ELEMENT);
		queueMgr.setId(OmqConstants.QUEUE_MANAGER_ELEMENT);
		XmlElement queueMgrNameEl = new XmlElement();
		queueMgrNameEl.setElementName(OmqConstants.QUEUE_MANAGER_NAME_ELEMENT);
		queueMgrNameEl.setId(OmqConstants.QUEUE_MANAGER_NAME_ELEMENT);
		queueMgrNameEl.setNodeValue(queueMgrName);
		
		
		XmlElement queue = new XmlElement();
		queue.setElementName(OmqConstants.QUEUE_ELEMENT);
		queue.setId(OmqConstants.QUEUE_ELEMENT);
		XmlElement queueNameEl = new XmlElement();
		queueNameEl.setElementName(OmqConstants.QUEUE_NAME_ELEMENT);
		queueNameEl.setId(OmqConstants.QUEUE_NAME_ELEMENT);
		queueNameEl.setNodeValue(queueName);
		queue.addElement(queueNameEl);
		
		queueMgr.addElement(queueMgrNameEl);
		queueMgr.addElement(queue);
		if((msg != null && !msg.equals("")) || (messageId != null && !messageId.equals(""))){
			XmlElement message = new XmlElement();
			message.setElementName(OmqConstants.MESSAGE_ELEMENT);
			XmlElement msgId = new XmlElement();
			msgId.setElementName(OmqConstants.MESSAGE_ID_ELEMENT);
			msgId.setId(OmqConstants.MESSAGE_ID_ELEMENT);
			msgId.setNodeValue(messageId);
			message.addElement(msgId);
			
			XmlElement msgBody = new XmlElement();
			msgBody.setElementName(OmqConstants.MESSAGE_BODY_ELEMENT);
			msgBody.setId(OmqConstants.MESSAGE_BODY_ELEMENT);
			msgBody.setNodeValue(msg.toString());
			message.addElement(msgBody);
			queue.addElement(message);
		}
		
		return queueMgr;
	}

	/**
	 * <session>
	 * <id>[#CDATA]</id>
     * <transactional>true/false</transactional>
     * <number_of_messages>0</number_of_messages>
     * </session>
	 */
	private XmlElement createRequestSession(String sessionId,String transactional, String numOfMessages){
		//Creating session root element
		XmlElement sessionEl = new XmlElement();
		sessionEl.setElementName(OmqConstants.SESSION_ELEMENT);
		sessionEl.setId(OmqConstants.SESSION_ELEMENT);
		
		//Creating child elements(as shown in the above method comment)
		XmlElement session_idEl = new XmlElement();
		session_idEl.setElementName(OmqConstants.SESSION_ID_ELEMENT);
		session_idEl.setId(OmqConstants.SESSION_ID_ELEMENT);
		session_idEl.setNodeValue(sessionId);
		System.out.println("session id : " + sessionId);
		XmlElement isTransactionEl = new XmlElement();
		isTransactionEl.setElementName(OmqConstants.SESSION_IS_TRANSACTION_ELEMENT);
		isTransactionEl.setId(OmqConstants.SESSION_IS_TRANSACTION_ELEMENT);
		isTransactionEl.setNodeValue(transactional);
		
		XmlElement numOfMsgsEl = new XmlElement();
		numOfMsgsEl.setElementName(OmqConstants.SESSION_NUM_OF_MESSAGES_ELEMENT);
		numOfMsgsEl.setId(OmqConstants.SESSION_NUM_OF_MESSAGES_ELEMENT);
		numOfMsgsEl.setNodeValue(numOfMessages);
		
		
		sessionEl.addElement(session_idEl);
		sessionEl.addElement(isTransactionEl);
		sessionEl.addElement(numOfMsgsEl);
		
		return sessionEl;
	}
}


